package com.example.volunteer.service.impl;

import com.example.volunteer.exception.CustomException;
import com.example.volunteer.mapper.AdminMapper;
import com.example.volunteer.mapper.VolunteerMapper;
import com.example.volunteer.model.Admin;
import com.example.volunteer.service.AdminService;
import com.example.volunteer.util.PageResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AdminServiceImpl implements AdminService {

    private final AdminMapper adminMapper;
    private final VolunteerMapper volunteerMapper;
    private final PasswordEncoder passwordEncoder;

    // 使用构造器注入代替字段注入
    public AdminServiceImpl(AdminMapper adminMapper,
                            VolunteerMapper volunteerMapper,
                            PasswordEncoder passwordEncoder) {
        this.adminMapper = adminMapper;
        this.volunteerMapper = volunteerMapper;
        this.passwordEncoder = passwordEncoder;
    }
    @Override
    public void createAdmin(Admin admin) {
        if (adminMapper.findByEmail(admin.getEmail()) != null) {
            throw new CustomException("邮箱已注册");
        }
        admin.setPassword(passwordEncoder.encode(admin.getPassword()));
        adminMapper.insert(admin);
    }

    @Override
    public Admin findById(String adminId) {
        return adminMapper.findById(adminId);
    }

    @Override
    public Admin findByEmail(String email) {
        return adminMapper.findByEmail(email);
    }

    private static final Logger log = LoggerFactory.getLogger(AdminServiceImpl.class);

    @Override
    public void update(Admin admin) {
        Admin existing= adminMapper.findById(admin.getAdminId());
        if (existing == null) {
            throw new CustomException("管理员不存在");
        }
        // 如果密码有变化，加密新密码
        if (admin.getPassword() == null || admin.getPassword().isEmpty()) {
            admin.setPassword(existing.getPassword());
        } else if (!admin.getPassword().equals(existing.getPassword())) {
            // 只有密码变化时才重新加密
            admin.setPassword(passwordEncoder.encode(admin.getPassword()));
        }
        adminMapper.update(admin);
    }

    @Override
    public void delete(Admin admin) {
        adminMapper.delete(admin);
    }

    @Override
    public PageResult<Admin> findAdminsWithPage(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Admin> admins = adminMapper.findAdminsWithPage(offset, pageSize);
        int total = adminMapper.countAdmins();

        PageResult<Admin> result = new PageResult<>();
        result.setData(admins);
        result.setTotal(total);
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setPages((int) Math.ceil((double) total / pageSize));

        return result;
    }

    @Override
    public PageResult<Admin> findByNameWithPage(String name, int pageNum, int pageSize) {
        return createPageResult(
                adminMapper.findByNameWithPage(name, calculateOffset(pageNum, pageSize), pageSize),
                adminMapper.countByName(name),
                pageNum,
                pageSize
        );
    }

    @Override
    public PageResult<Admin> findByEmailWithPage(String email, int pageNum, int pageSize) {
        return createPageResult(
                adminMapper.findByEmailWithPage(email, calculateOffset(pageNum, pageSize), pageSize),
                adminMapper.countByEmail(email),
                pageNum,
                pageSize
        );
    }

    @Override
    public PageResult<Admin> findByContactWithPage(String contact, int pageNum, int pageSize) {
        return createPageResult(
                adminMapper.findByContactWithPage(contact, calculateOffset(pageNum, pageSize), pageSize),
                adminMapper.countByContact(contact),
                pageNum,
                pageSize
        );
    }

    private int calculateOffset(int pageNum, int pageSize) {
        return (pageNum - 1) * pageSize;
    }

    private PageResult<Admin> createPageResult(List<Admin> data, int total, int pageNum, int pageSize) {
        PageResult<Admin> result = new PageResult<>();
        result.setData(data);
        result.setTotal(total);
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setPages((int) Math.ceil((double) total / pageSize));
        return result;
    }
}
